/**
 * 3η ΓΕ 2013-2014 - Super Market
 * ΦΡΑΓΚΟΥΛΟΠΟΥΛΟΥ ΕΜΜΑΝΟΥΕΛΑ (69298)
 * ΧΑΛΔΑΣ ΧΑΡΑΛΑΜΠΟΣ (69305)
 * ΧΟΡΜΟΒΙΤΗΣ ΙΩΑΝΝΗΣ (69325)
 * ΧΟΥΣΤΟΥΛΑΚΗ ΕΥΑΓΓΕΛΙΑ (69327)
 */
package simulation;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;
import javax.persistence.TypedQuery;
import model.*;
import supermarket.EntityManagerFactory;

/**
 * Methods γενικής χρήσης
 */
public class GeneralLib {
  
    /*
    Επιλέγει και επιστρέφει έναν Πελάτη από το Table CUSTOMER
    */
    public static synchronized Customer pickCustomer () {
        
        
        // Διαβάζω όλους τους Πελάτες και γεμίζω ένα List<Customer>
        TypedQuery<Customer> query = EntityManagerFactory.getEntityManager()
                .createNamedQuery("Customer.findAll", Customer.class);
        List<Customer> list = query.getResultList();
        
        // Βρίσκω έναν τυχαίο ακέραιο από 0 έως το πλήθος των Πελατών
        Random random = new Random ();
        int index = random.nextInt(list.size());
        
        // Επιστρέφω τον Πελάτη στη θέση index
        return list.get(index);
    }
    
    /*
    Επιλέγει και επιστρέφει ένα Κατάστημα από το Table STORE
    */
    public static synchronized Store pickStore () {
        
        // Διαβάζω όλα τα Καταστήματα και γεμίζω ένα List<Store>
        TypedQuery<Store> query = EntityManagerFactory.getEntityManager()
                .createNamedQuery("Store.findAll", Store.class);
        List<Store> list = query.getResultList();
        
        // Βρίσκω έναν τυχαίο ακέραιο από 0 έως το πλήθος των Καταστημάτων
        Random random = new Random ();
        int index = random.nextInt(list.size());
        
        // Επιστρέφω το Κατάστημα στη θέση index
        return list.get(index);
    }
    
    /*
    Επιλέγει και επιστρέφει από 1 έως 20 Προϊόντα
    */
    public static synchronized List<Product>  pickProducts (Store store) {
        // Βρίσκω έναν τυχαίο ακέραιο από 0 έως το 20, 
        // για το πλήθοςτων προϊόντων
        Random random = new Random ();
        int prodCount = random.nextInt(20);
        
        
        // Διαβάζω όλα τα Προιόντα του Καταστήματος 
        // και γεμίζω ένα List<Product>
        EntityManagerFactory.getEntityManager().refresh(store);
        List<Product> list = store.getProductList();
        
        List<Product> prodList = new ArrayList<>();
        
        for (int i=0; i<prodCount; i++) {
           int index = random.nextInt(list.size());
           prodList.add(list.get(index));
        }
        
        return prodList;
    }
    
    
    public static synchronized Purchase createPurchase () {
        Customer cust = pickCustomer ();
        Store store = GeneralLib.pickStore();
        
        Purchase purchase = new Purchase();            // Νέα Αγορά
        purchase.setDatetime(new java.util.Date());    // Ημερομηνία
        purchase.setCustomer(cust);    // Πελάτης   (τυχαία επιλογή)                
        purchase.setStore(store);      // Κατάστημα (τυχαία επιλογή)
        
        //  1 έως 20 προϊόντα (τυχαία επιλογή)
        List<Product> products = pickProducts (store);
        
        // Μεταβλητές για τον Υπολογισμό Συνόλων
        int points_earned=0;
        float amount = 0;
        
        // Για κάθε προϊόν, ορίζω τυχαία ποσότητα (από 1 έως 20 τεμάχια)
        // και το προσθέτω στη λίστα.
        Random random = new Random();
        List<ProductPurchase> ppList = new ArrayList<> ();
        for(Product prod:products){
            int quantity = random.nextInt(20)+1;
            
            
            ProductPurchase pp = new ProductPurchase();
            pp.setProductId(prod);
            pp.setQuantity(quantity);         
            ppList.add(pp);
            
            // Σύνολα
            points_earned += prod.getPoints() * quantity;
            amount += prod.getPrice() * quantity;
        }
        purchase.setProductPurchaseList (ppList);
   
        // Τελικά Σύνολα
        purchase.setPointsEarned(points_earned);
        purchase.setAmount(amount);
        
        // Παράδοση στην Οικία μόνο αν υπάρχει διεύθυνση
        Boolean atHome = (cust.getAddress() != null && !cust.getAddress().trim().equals(""));
        purchase.setDelivery(atHome);
        
        
        return purchase;
    }
    
    public static synchronized Boolean savePurchase (Purchase purchase) {
        EntityManagerFactory.getEntityManager().getTransaction().begin();
        try {
            for(ProductPurchase pp:purchase.getProductPurchaseList()){
                pp.setPurchaseId(purchase);
                EntityManagerFactory.getEntityManager().persist(pp);
            }
            
         
            EntityManagerFactory.getEntityManager().persist(purchase);            
            
            // Επιταγές
            int newCheques = purchase.getPointsEarned() / 200;
            // create new Cheques
            for (int i = 0; i < newCheques; ++i) {
                Cheques chk = new Cheques();
                chk.setCreationDate(new Date());
                chk.setCustomerId(purchase.getCustomer());
                chk.setIsvalid(true);
                EntityManagerFactory.getEntityManager().persist(chk);
            }
            EntityManagerFactory.getEntityManager().getTransaction().commit();
            return true;
        } 
        catch (Exception e) {
            e.printStackTrace();
            EntityManagerFactory.getEntityManager().getTransaction().rollback();
        }
        
        return false;
    }
}
